import IO
import System
import Char
import List


lowercase = map toLower

wordInList :: String -> [String] -> Bool
{-
    Return a boolean representing whether the string is in the list.
-}
wordInList _ [] =
    False

wordInList check_against (x:xs) =
    if (check_against == (lowercase x)) then True else wordInList check_against xs
    

removeWord :: String -> [String] -> [String]
{-
    Return the list of string without the specified string.
-}
removeWord _ [] =
    []
removeWord to_remove (x:xs) =
    if (to_remove == (lowercase x)) then removeWord to_remove xs else (x : (removeWord to_remove xs))
    

checkWords :: Handle -> [String] -> IO [String]
{-
    Check if any of the strings in the list match any line returned by the
    Handle.
-}
checkWords dict_file to_check =
    do
        {- Hugs does not provide IO.hIsEOF; has IO.hugsHIsEOF which tells you
            if the last file read hit EOF (like C's feof()); see
            http://cvs.haskell.org/Hugs/pages/hugsman/diffs.html for details.
        -}
        eof <- hIsEOF dict_file
        if eof then return to_check else
            do
                cased_check_against <- hGetLine dict_file
                let check_against = lowercase cased_check_against
                if (wordInList check_against to_check) then
                    checkWords dict_file (removeWord check_against to_check)
                    else checkWords dict_file to_check


main =
    do
        -- Hugs does not define hSetBuffering.
        --hSetBuffering dict_file LineBuffering
        args_list <- getArgs
        dict_file <- openFile (args_list !! 0) ReadMode
        let check_words = words (args_list !! 1)
        misspelled_words <- checkWords dict_file check_words
        putStr (unlines misspelled_words) 
        hClose dict_file
